ChangeFeedProcessor: Fixes first-change skip during initial startup by anchoring StartTime#5617
Merged
kirankumarkolli merged 14 commits intoApr 8, 2026
Conversation
Addresses #5268 by setting an implicit StartTime during first StartAsync when no explicit start options are set. Also adds unit coverage for StartTime option behavior and an emulator regression test for immediate writes after StartAsync.
…r-startasync-5268
…r-startasync-5268
…r-startasync-5268
Member
|
Please update Title with initialization state also |
…r-startasync-5268
Address review feedback to handle case where more than 10 docs could be processed in the callback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
NaluTripician
commented
Mar 4, 2026
Contributor
Author
NaluTripician
left a comment
There was a problem hiding this comment.
Re: DynamicTests.cs line 116 — @kirankumarkolli
Good catch — the == 10 check is fragile. If the callback fires with a batch that crosses 10 (e.g., count goes from 8→12), the ManualResetEvent would never be set and the test would time out. Changed to >= 10 to be defensive. Pushed in a4dec3f.
Contributor
Author
|
Updated the PR title to include initialization state context as requested. |
This was referenced May 1, 2026
ananth7592
added a commit
that referenced
this pull request
May 4, 2026
…llVersionsAndDeletes Moves the abstract method declaration out of the #if PREVIEW block so it compiles into the GA (non-preview) build output. Added a check inside ChangeFeedProcessorCore that skips appending startTime fix done as part of #5617 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ananth7592
added a commit
that referenced
this pull request
May 4, 2026
…llVersionsAndDeletes Moves the abstract method declaration out of the #if PREVIEW block so it compiles into the GA (non-preview) build output. Added a check inside ChangeFeedProcessorCore that skips appending startTime fix done as part of #5617 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ananth7592
added a commit
that referenced
this pull request
May 4, 2026
…llVersionsAndDeletes Moves the abstract method declaration out of the #if PREVIEW block so it compiles into the GA (non-preview) build output. Added a check inside ChangeFeedProcessorCore that skips appending startTime fix done as part of #5617 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced May 4, 2026
ananth7592
added a commit
that referenced
this pull request
May 12, 2026
…llVersionsAndDeletes Moves the abstract method declaration out of the #if PREVIEW block so it compiles into the GA (non-preview) build output. Added a check inside ChangeFeedProcessorCore that skips appending startTime fix done as part of #5617 Contract changes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ananth7592
added a commit
that referenced
this pull request
May 12, 2026
…llVersionsAndDeletes Moves the abstract method declaration out of the #if PREVIEW block so it compiles into the GA (non-preview) build output. Added a check inside ChangeFeedProcessorCore that skips appending startTime fix done as part of #5617 Contract changes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ananth7592
added a commit
that referenced
this pull request
May 14, 2026
…llVersionsAndDeletes Moves the abstract method declaration out of the #if PREVIEW block so it compiles into the GA (non-preview) build output. Added a check inside ChangeFeedProcessorCore that skips appending startTime fix done as part of #5617 Contract changes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced May 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes issue #5268 where
ChangeFeedProcessorcan skip the first change when started without explicit start options.Bug Description
When
ChangeFeedProcessoris started with default options (noWithStartTime, no continuation, no start-from-beginning), it uses the default start-from-now path.This path anchors at the first service read (
IfNoneMatch: *) rather than atStartAsync()call time. Because startup includes asynchronous lease acquisition and load balancing, there is a window where documents can be written afterStartAsync()returns but before the first read reaches the backend. Those documents can be skipped.Root Cause
PartitionLoadBalancerCore.Start()schedules background work and returns immediately.Nowbehavior is based on first read timing, notStartAsync()timing.Fix
In
ChangeFeedProcessorCore.StartAsync():StartFromBeginning == falseStartTime == nullStartContinuationis null/emptychangeFeedProcessorOptions.StartTime = DateTime.UtcNowbefore async initialization.This anchors start behavior at processor startup time and closes the timing gap.
Why This Is Safe
Tests Added
Unit tests
Microsoft.Azure.Cosmos.Tests/ChangeFeed/ChangeFeedProcessorCoreTests.csStartAsync_SetsStartTime_WhenNoStartOptionsProvidedStartAsync_DoesNotOverrideExplicitStartTimeStartAsync_DoesNotSetStartTime_WhenStartFromBeginningEmulator regression test
Microsoft.Azure.Cosmos.EmulatorTests/ChangeFeed/DynamicTests.csTestWithRunningProcessor_ImmediateWriteAfterStartValidation
A/B test on the new emulator regression
Additional checks
Files Changed
Microsoft.Azure.Cosmos/src/ChangeFeedProcessor/ChangeFeedProcessorCore.csMicrosoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/ChangeFeedProcessorCoreTests.csMicrosoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/ChangeFeed/DynamicTests.cs